package org.hackystat.sdsa.analyzer.control.compressor;

import java.util.ArrayList;
import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

import org.hackystat.sdsa.analyzer.model.activity.Activity;
import org.hackystat.sdsa.analyzer.model.activity.edit.DocumentEditActivity;
import org.hackystat.sdsa.analyzer.model.activity.edit.ProductionEditActivity;
import org.hackystat.sdsa.analyzer.model.activity.edit.UnitTestEditActivity;
import org.hackystat.sdsa.analyzer.model.activity.refactoring.BinaryRefactorActivity;
import org.hackystat.sdsa.analyzer.model.activity.refactoring.RefactorOperator;
import org.hackystat.sdsa.analyzer.model.activity.refactoring.RefactorSubjectType;
import org.hackystat.sdsa.analyzer.model.activity.refactoring.UnaryRefactorActivity;
import org.hackystat.utilities.tstamp.Tstamp;
import org.junit.Before;

/**
 * Provides common data for testing purpose.
 * 
 * @author hongbing
 *
 */
public class CompressorTestCommon {
  /** List of doc edit activities. */
  protected List<Activity> docActivityList;
  /** List of product edit activities. */
  protected List<Activity> prodActivityList;
  /** List of test edit activities. */
  protected List<Activity> testActivityList;
  /** All types of edit activity. */
  protected List<Activity> allEditActivityList;
  /** Refactor list. */
  protected List<Activity> refactoringActivityList;
  
  /**
   * Adds document edit activity.
   * 
   * @param activityList Activity list.
   * @throws Exception If problem occurs.
   */
  private void addDocEdit(List<Activity> activityList) throws Exception {
    String docFile1 = "file:/c:/com/foo/bar/package.html";
    XMLGregorianCalendar tstamp1 = Tstamp.makeTimestamp("2005-01-01T08:30:45");
    DocumentEditActivity docEdit1 = new DocumentEditActivity();
    docEdit1.setTimeStamp(tstamp1);
    docEdit1.setResourceUri(docFile1);
    docEdit1.setFileSize(100);
    activityList.add(docEdit1);
    
    DocumentEditActivity docEdit2 = new DocumentEditActivity();
    docEdit2.setTimeStamp(Tstamp.incrementMinutes(tstamp1, 1));
    docEdit2.setResourceUri(docFile1);
    docEdit2.setFileSize(125);
    activityList.add(docEdit2);
    
    DocumentEditActivity docEdit3 = new DocumentEditActivity();
    docEdit3.setTimeStamp(Tstamp.incrementSeconds(tstamp1, 110));
    docEdit3.setResourceUri(docFile1);
    docEdit3.setFileSize(127);
    activityList.add(docEdit3);
    
    String docFile2 = "file:/c:/com/foo/bar/index.jsp";
    XMLGregorianCalendar tstamp2 = Tstamp.makeTimestamp("2005-01-01T010:38:05");
    DocumentEditActivity docEdit4 = new DocumentEditActivity();
    docEdit4.setTimeStamp(tstamp2);
    docEdit4.setResourceUri(docFile2);
    docEdit4.setFileSize(560);
    activityList.add(docEdit4);
  }
  
  /**
   * Adds production edit activity.
   * 
   * @param activityList Activity list.
   * @throws Exception If problem occurs.
   */
  private void addProdEdit(List<Activity> activityList) throws Exception {
    String prodEditFile1 = "file:/c:/com/foo/bar/Foo.java";
    XMLGregorianCalendar tstamp1 = Tstamp.makeTimestamp("2006-12-01T10:00:00");
    ProductionEditActivity prodEdit1 = new ProductionEditActivity();
    prodEdit1.setTimeStamp(tstamp1);
    prodEdit1.setResourceUri(prodEditFile1);
    prodEdit1.setFileSize(100);
    prodEdit1.setNumOfMethods(2);
    prodEdit1.setMethodIncrease(2);
    prodEdit1.setNumOfStatements(100);
    prodEdit1.setStatementIncrease(100);
    activityList.add(prodEdit1);
    
    ProductionEditActivity prodEdit2 = new ProductionEditActivity();
    prodEdit2.setTimeStamp(Tstamp.incrementMinutes(tstamp1, 1));
    prodEdit2.setResourceUri(prodEditFile1);
    prodEdit2.setFileSize(125);
    prodEdit2.setNumOfMethods(5);
    prodEdit2.setMethodIncrease(3);
    prodEdit2.setNumOfStatements(300);
    prodEdit2.setStatementIncrease(200);
    activityList.add(prodEdit2);
    
    ProductionEditActivity prodEdit3 = new ProductionEditActivity();
    prodEdit3.setTimeStamp(Tstamp.incrementSeconds(tstamp1, 110));
    prodEdit3.setResourceUri(prodEditFile1);
    prodEdit3.setFileSize(127);
    prodEdit3.setNumOfMethods(8);
    prodEdit3.setMethodIncrease(3);
    prodEdit3.setNumOfStatements(930);
    prodEdit3.setStatementIncrease(630);
    activityList.add(prodEdit3);
    
    String prodFile2 = "file:/c:/com/foo/bar/Bar.java";
    XMLGregorianCalendar tstamp2 = Tstamp.makeTimestamp("2006-12-01T010:38:05");
    ProductionEditActivity prodEdit4 = new ProductionEditActivity();
    prodEdit4.setTimeStamp(tstamp2);
    prodEdit4.setResourceUri(prodFile2);
    prodEdit4.setFileSize(10);
    prodEdit4.setNumOfMethods(1);
    prodEdit4.setMethodIncrease(1);
    prodEdit4.setNumOfStatements(25);
    prodEdit4.setStatementIncrease(25);
    activityList.add(prodEdit4);

    ProductionEditActivity prodEdit5 = new ProductionEditActivity();
    prodEdit5.setTimeStamp(Tstamp.incrementSeconds(tstamp2, 110));
    prodEdit5.setResourceUri(prodFile2);
    prodEdit5.setFileSize(80);
    prodEdit5.setNumOfMethods(3);
    prodEdit5.setMethodIncrease(2);
    prodEdit5.setNumOfStatements(30);
    prodEdit5.setStatementIncrease(5);
    activityList.add(prodEdit5);
  }

  
  /**
   * Adds test edit activity.
   * 
   * @param activityList Activity list.
   * @throws Exception If problem occurs.
   */
  private void addTestEdit(List<Activity> activityList) throws Exception {
    String testEditFile1 = "file:/c:/com/foo/bar/TestFoo.java";
    XMLGregorianCalendar tstamp1 = Tstamp.makeTimestamp("2006-12-20T10:00:00");
    UnitTestEditActivity testEdit1 = new UnitTestEditActivity();
    testEdit1.setTimeStamp(tstamp1);
    testEdit1.setResourceUri(testEditFile1);
    testEdit1.setFileSize(100);
    testEdit1.setNumOfMethods(2);
    testEdit1.setMethodIncrease(2);
    
    testEdit1.setNumOfStatements(100);
    testEdit1.setStatementIncrease(100);
    testEdit1.setNumOfTestAssertions(3);
    testEdit1.setTestAssertionIncrease(3);

    activityList.add(testEdit1);
    
    UnitTestEditActivity testEdit2 = new UnitTestEditActivity();
    testEdit2.setTimeStamp(Tstamp.incrementMinutes(tstamp1, 1));
    testEdit2.setResourceUri(testEditFile1);
    testEdit2.setFileSize(125);
    testEdit2.setNumOfMethods(5);
    testEdit2.setMethodIncrease(3);
    testEdit2.setNumOfTestMethods(5);
    testEdit2.setTestMethodIncrease(3);
    testEdit2.setNumOfStatements(300);
    testEdit2.setStatementIncrease(200);
    testEdit2.setNumOfTestAssertions(6);
    testEdit2.setTestAssertionIncrease(3);
    
    activityList.add(testEdit2);
    
    UnitTestEditActivity testEdit3 = new UnitTestEditActivity();
    testEdit3.setTimeStamp(Tstamp.incrementSeconds(tstamp1, 110));
    testEdit3.setResourceUri(testEditFile1);
    testEdit3.setFileSize(127);
    testEdit3.setNumOfMethods(8);
    testEdit3.setMethodIncrease(3);
    testEdit3.setNumOfTestMethods(7);
    testEdit3.setTestMethodIncrease(2);

    testEdit3.setNumOfStatements(930);
    testEdit3.setStatementIncrease(630);
    testEdit3.setNumOfTestAssertions(8);
    testEdit3.setTestAssertionIncrease(2);

    activityList.add(testEdit3);
    
    String testFile2 = "file:/c:/com/foo/bar/TestBar.java";
    XMLGregorianCalendar tstamp2 = Tstamp.makeTimestamp("2006-12-01T010:38:05");
    UnitTestEditActivity testEdit4 = new UnitTestEditActivity();
    testEdit4.setTimeStamp(tstamp2);
    testEdit4.setResourceUri(testFile2);
    testEdit4.setFileSize(10);
    testEdit4.setNumOfMethods(1);
    testEdit4.setMethodIncrease(1);
    testEdit4.setNumOfTestMethods(0);
    testEdit4.setTestMethodIncrease(0);
    testEdit4.setNumOfStatements(25);
    testEdit4.setStatementIncrease(25);
    testEdit4.setNumOfTestAssertions(10);
    testEdit4.setTestAssertionIncrease(10);

    activityList.add(testEdit4);

    UnitTestEditActivity testEdit5 = new UnitTestEditActivity();
    testEdit5.setTimeStamp(Tstamp.incrementSeconds(tstamp2, 110));
    testEdit5.setResourceUri(testFile2);
    testEdit5.setFileSize(80);
    testEdit5.setNumOfMethods(3);
    testEdit5.setMethodIncrease(2);
    testEdit5.setNumOfTestMethods(1);
    testEdit5.setTestMethodIncrease(1);

    testEdit5.setNumOfStatements(30);
    testEdit5.setStatementIncrease(5);
    testEdit5.setNumOfTestAssertions(13);
    testEdit5.setTestAssertionIncrease(3);

    activityList.add(testEdit5);
  }

  /**
   * Adds refactoring activities to the list.
   * 
   * @param activityList Activity list.
   * @throws Exception If problem occurs.
   */
  private void addRefactoring(List<Activity> activityList) throws Exception {
    RefactorOperator ADD = RefactorOperator.getInstance("ADD");
    RefactorOperator RENAME = RefactorOperator.getInstance("RENAME");
    RefactorSubjectType FIELD = RefactorSubjectType.getInstance("FIELD");
    RefactorSubjectType METHOD = RefactorSubjectType.getInstance("METHOD");
    
    XMLGregorianCalendar tstamp = Tstamp.makeTimestamp("2005-01-01T08:30:45");
    String refactoredFile = "file:/c:/com/foo/bar/Foo.java";
    UnaryRefactorActivity addActivity = new UnaryRefactorActivity(ADD, FIELD);
    addActivity.setTimeStamp(tstamp);
    addActivity.setResourceUri(refactoredFile);
    addActivity.setSubjectName("void set");
    activityList.add(addActivity);
    
    BinaryRefactorActivity renameActivity = new BinaryRefactorActivity(RENAME, FIELD);
    renameActivity.setTimeStamp(Tstamp.incrementSeconds(tstamp, 10));
    renameActivity.setResourceUri(refactoredFile);
    renameActivity.setFromSubject("set");
    renameActivity.setToSubject("void setUp");
    activityList.add(renameActivity);
    
    BinaryRefactorActivity renameActivity2 = new BinaryRefactorActivity(RENAME, METHOD);
    renameActivity2.setTimeStamp(Tstamp.incrementSeconds(tstamp, 35));
    renameActivity2.setResourceUri(refactoredFile);
    renameActivity2.setFromSubject("setUp");
    renameActivity2.setToSubject("void setUp()");
    activityList.add(renameActivity2);
  }
  
  /**
   * Prepare data for testing.
   * 
   * @throws Exception If problem occurs.
   */
  @Before public void setUp() throws Exception  {
    this.docActivityList = new ArrayList<Activity>();
    addDocEdit(this.docActivityList);
    
    this.prodActivityList = new ArrayList<Activity>();
    addProdEdit(this.prodActivityList);

    this.testActivityList = new ArrayList<Activity>();
    addTestEdit(this.testActivityList);
    
    this.allEditActivityList = new ArrayList<Activity>();
    addDocEdit(this.allEditActivityList);
    addProdEdit(this.allEditActivityList);
    addTestEdit(this.allEditActivityList);
    
    this.refactoringActivityList = new ArrayList<Activity>();
    addRefactoring(refactoringActivityList);
  }
}
